import string
import re
import validateType
import global_objects as go

tables = []
wrong_ir = 'Wrong row description. It should be: table_name(number_of_columns, number_of_rows) ! ' 
wrong_rr = 'Wrong row description. It should be: column_name : type(arguments) ! ' 
def initial_row(row):
    m =re.match('^(\s*\w*\s*)(\s*\(\s*)(\s*[0-9]+\s*)(\s*,\s*)(\s*[0-9]+\s*)(\s*\)\s*)', row)
    if m==None:
        return False
    else:
        return True
    

#m.group(0) #the matched string
#m.group(1) #table name
#m.group(2) # (
#m.group(3) # 12 - number of attributes 
#m.group(4) # ,
#m.group(5) # 500 - number of desired rows in the table
#m.group(6) # )

    
def split_methadata(fname):  
    f = open(fname, 'r')
    rows = f.readlines()
    rows = map(string.strip,rows) #delete white spaces in the beginning and at the end of each row
    rows = filter(lambda x: re.search('\S+',x)!=None , rows) #delete all empty rows
    i=-1
    for line in rows:
        if initial_row(line)==True:
            i+=1
            tables.append([line])
        else:
            tables[i].append(line)
	f.close()
    return tables
# ____________________________INIT ROWS___________________________________

def valTablName(row):
    if initial_row(row):
        name = row.split('(')[0].strip()
        m = re.match('\S+\s+\S+', name)
        if m != None:
            go.errMessage = 'Wrong table name :'+ name+ '! It should not contain whitespaces or dots!'
            return False
        else:
            return True
    else:
        go.errMessage =  'In line :  '+ row + ' ! '+ wrong_ir
        return False
    
def valColRowCount(row):
    if initial_row(row):
        m =re.match('^(\s*\w*\s*)(\s*\(\s*)(\s*[-]*\s*[0-9]+\s*)(\s*,\s*)(\s*[-]*\s*[0-9]+\s*)(\s*\)\s*)', row)
        if m == None:
            go.errMessage =  'In line :  '+ row + ' ! '+ wrong_ir
            return False
        else:
            if int(m.group(3))<=0 or int(m.group(5))<=0:
                if int(m.group(3))<=0:
                    go.errMessage =  'Wrong columns count. It should be greater than 0 ! ' + 'In line :  '+ row + ' ! '
                if int(m.group(5))<=0:
                    go.errMessage =  'Wrong rows count. It should be greater than 0 ! '+'In line :  '+ row + ' ! '
                return False
            else:
                return True
    else:
        go.errMessage =  'In line :  '+ row + ' ! '+ wrong_ir
        return False
#_____public_____
def valInitRow(row):
    return valTablName(row) and valColRowCount(row) 
#_________________________REGULAR ROWS___________________________________

#_____public_____

def valColName(row):
    if row.count(':')>1 or row.count(':')==0:
        go.errMessage =  row + '\n' + wrong_rr 
        return False
    if row.split(':')[0].strip().find('.')!=-1:
        go.errMessage =  row + '\n' + 'Wrong column name! It should not contain dots !' 
        return False
    colName = row.split(':')[0].strip()
    m = re.match('\S+\s+\S+', colName)
    if m != None:
        go.errMessage =  'Wrong column name: '+ colName+ '! It should not contain whitespaces !'
        return False
    else:
        return True
#_________________________TABLE CORRECTNESS___________________________    

#_____public_____

def valColCount(table):
    m =re.match('^(\s*\w*\s*)(\s*\(\s*)(\s*[-]*\s*[0-9]+\s*)(\s*,\s*)(\s*[-]*\s*[0-9]+\s*)(\s*\)\s*)', table[0])
    colCount = int(m.group(3))
    return colCount == (len(table) - 1)

#_________________________REFERENCE CORRECTNESS_______________________    
def pk(row):
    return re.search('\s*,\s*[pP]\s*,\s*',row.split(':')[1].strip())!= None

def findColInTbl(col, table): # col is name of column, table is ['product(1, 10)', 'prod_id : numeric (, , 1, , , , p , )', 'price : numeric']
    for i in range(1, len(table)):
        if table[i].split(':')[0].strip() == col.strip() and pk(table[i]):
            return True
        else:
            return False
def valFKRef(pk):# pk - primary key, table.key
    split_methadata()
    args = pk.split('.')
    tname = args[0].strip()
    kname = args[1].strip()
    table = filter(lambda x: x[0].split('(')[0].strip() == tname, tables) # table=[['table_name(1,2,)','id:number(1,p ,)]]
    if table==[]:
        return False
    elif findColInTbl(kname, table[0]):
        return True
    else:
        return False
def fk(row):
    return re.search('\s*,\s*[Ff]\s*,\s*',row.split(':')[1].strip())!= None

#_________________________FILE CORRECTNESS____________________________

def validation(fname):
    split_methadata(fname)
    for i in range(0,len(tables)):
        if valColCount(tables[i])== False: # Checks if columns count in each table is as specified in the initial row
            go.errMessage =  'Table ' + tables[i][0].split('(')[0].strip() + ' :Given more columns than expected!'
            return False
        valColCount(tables[i])
        valInitRow(tables[i][0])
        for j in range(1, len(tables[i])):
            if not valColName(tables[i][j]):
                return False
            if not validateType.validateColumnType(tables[i][j].split(':')[1].strip().lower()):
                return False
    return True
                
                
        
#print pk('emp_id:numeric(, , 1, , , , p, )')       
